/**
 * Beyondo licenses this file to You under the GNU General Public
 * License, Version 3.0 (the "License");
 * 
 * You may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.gnu.org/licenses/lgpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.beyondo.sgs.client.protocol.simple {
	
/**
 * SGS Protocol constants.
 * <p>
 * A protocol message is constructed as follows:
 * <ul>
 * <li> (unsigned short) payload length, not including this field
 * <li> (byte) operation code
 * <li> optional content, depending on the operation code.
 * </ul>
 * </p>
 * <p>
 * A {@code ByteArray} is encoded as follows:
 * <ul>
 * <li> (byte[]) the bytes in the array
 * </ul>
 * </p>
 * <p>
 * <b>Note:</b> Messages may need to include explicit array length fields
 * if they include more than one ByteArray.
 * </p>
 * <p>
 * A {@code String} is encoded as follows:
 * <ul>
 * <li> (unsigned short) number of bytes of modified UTF-8 encoded String
 * <li> (byte[]) String encoded in modified UTF-8 as described
 * in {@link java.io.DataInput}
 * </ul>
 * </p>
 */
 	public class SimpleSgsProtocol {
		/**
		 * The maximum length a protocol message field defined as a
		 * <code>String</code> or <code>byte[]</code>: 
		 * <code>MAX_MESSAGE_LENGTH</code> bytes.
		 */
		public static const MAX_MESSAGE_LENGTH:int = 65535;
		
    /**
     * The maximum payload length:
     * {@value #MAX_PAYLOAD_LENGTH} bytes.
     */
    public static const MAX_PAYLOAD_LENGTH:int = 65532;		

		/** The version number, currently <code>0x04</code>. */
		public static const VERSION:int = 0x04;
		
		/**
		 * Login request from a client to a server. <br/>
		 * Opcode: <code>0x10</code> <br/>
		 * Payload:
		 * <ul>
		 * <li>(byte)   protocol version</li>
 		 * <li>(String) name</li>
		 * <li>(String) password</li>
		 * </ul>
		 */
    public static const LOGIN_REQUEST:int = 0x10;
    	
		/**
		 * Login success. Server response to a client's
		 * <code>LOGIN_SUCCESS</code>. <br >
		 * Opcode: <code>0x11</code> <br/>
		 * Payload:
		 * <ul>
		 * <li> (ByteArray) reconnectionKey
		 * </ul>
		 */
		public static const LOGIN_SUCCESS:int = 0x11;

		/**
		 * Login failure. Server response to a client's
		 * <code>LOGIN_REQUEST</code>. <br />
		 * Opcode: <code>0x12</code> <br />
		 * Payload:
		 * <ul>
		 * <li> (String) reason
		 * </ul>
		 */
		public static const LOGIN_FAILURE:int = 0x12;
		
    /**
     * Login redirect. Server response to a client's
     * <code>LOGIN_REDIRECT</code>.<br />
     * Opcode: <code>0x13</code><br />
     * Payload:
     * <ul>
     * <li> (String)	hostname
     * <li> (int)			port
     * </ul>
     */
		public static const LOGIN_REDIRECT:int = 0x13;	
		
    /**
     * Reconnection request.  Client requesting reconnect to a server.
     * <code>RECONNECT_REQUEST</code>.<br />
     * Opcode: <code>0x20</code><br />
     * Payload:
     * <ul>
     * <li> (byte)      protocol version
     * <li> (ByteArray) reconnectionKey
     * </ul>
     */
    public static const RECONNECT_REQUEST:int = 0x20;
		
    /**
     * Reconnect success.  Server response to a client's
     * <code>RECONNECT_REQUEST</code>.<br />
     * Opcode: <code>0x21</code><br />
     * Payload:
     * <ul>
     * <li> (ByteArray) reconnectionKey</li>
     * </ul>
     */
		public static const RECONNECT_SUCCESS:int = 0x21;
		
    /**
     * Reconnect failure.  Server response to a client's
     * <code>RECONNECT_REQUEST</code>.<br />
     * Opcode: <code>0x22</code><br />
     * Payload:
     * <ul>
     * <li> (String) reason</li>
     * </ul>
     */
		public static const RECONNECT_FAILURE:int = 0x22;
		
		/**
     * Session message.  May be sent by the client or the server.
     * Maximum length is <code>MAX_PAYLOAD_LENGTH</code> bytes.
     * Larger messages require fragmentation and reassembly above
     * this protocol layer.
		 * Opcode: <code>0x30</code> <br/>
     * <ul>
     * <li> (ByteArray) message
     * </ul>
 		 */
		public static const SESSION_MESSAGE:int = 0x30;
		
    /**
     * Logout request from a client to a server.<br />
     * Opcode: <code>0x40</code><br />
     * No payload.
     */
		public static const LOGOUT_REQUEST:int = 0x40;
		
    /**
     * Logout success.  Server response to a client's <code>LOGOUT_REQUEST</code>.
     * <br />
     * Opcode: <code>0x41</code><br />
     * No payload.
     */
		public static const LOGOUT_SUCCESS:int = 0x41;
		
		/**
		 * Channel join. Server notifying a client that it has joined a channel.
		 * <br/>
		 * Opcode: <code>0x50</code> <br />
		 * Payload:
		 * <ul>
		 * <li> (String) channel name
		 * <li> (ByteArray) channel ID
		 * </ul>
		 */
		public static const CHANNEL_JOIN:int = 0x50;
		
		/**
		 * Channel leave. Server notifying a client that it has left a channel.<br />
		 * Opcode: <code>0x51</code><br />
		 * Payload:
		 * <ul>
		 * <li> (ByteArray) channel ID
		 * </ul>
		 */
		public static const CHANNEL_LEAVE:int = 0x51;
		
    /**
     * Channel message.  May be sent by the client or the server.
     * Maximum length is <code>MAX_PAYLOAD_LENGTH</code> bytes.
     * Larger messages require fragmentation and reassembly above
     * this protocol layer.<br />
		 * Opcode: <code>0x52</code><br />
     * Payload:
     * <ul>
     * <li> (unsigned short) channel ID size
     * <li> (ByteArray) channel ID
     * <li> (ByteArray) message
     * </ul>
     */
		public static const CHANNEL_MESSAGE:int = 0x52;
		
		public static function toString(val:int) : String {
			switch(val) {
				case LOGIN_REQUEST:
					return "LOGIN REQUEST";
				case LOGIN_SUCCESS:
					return "LOGIN SUCCESS";
				case LOGIN_FAILURE:
					return "LOGIN FAILURE";
				case LOGIN_REDIRECT:
					return "LOGIN REDIRECT";
				case RECONNECT_REQUEST:
					return "RECONNECT REQUEST";
				case RECONNECT_SUCCESS:
					return "RECONNECT SUCCESS";
				case RECONNECT_FAILURE:
					return "RECONNECT FAILURE";
				case SESSION_MESSAGE:
					return "SESSION MESSAGE";
				case LOGOUT_REQUEST:
					return "LOGOUT REQUEST";
				case LOGOUT_SUCCESS:
					return "LOGOUT SUCCESS";
				case CHANNEL_JOIN:
					return "CHANNEL JOIN";
				case CHANNEL_LEAVE:
					return "CHANNEL LEAVE";
				case CHANNEL_MESSAGE:
					return "CHANNEL MESSAGE";
				default:
					return "UNKMOWN COMMAND";
			}
		}
	}
}